﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ForumsBrowser
{
    public static class IListExtensions
    {
        public static void AddUnique<T>(this IList<T> _this, T item)
        {
            if (_this.Contains(item))
                _this.Remove(item);
            _this.Add(item);
        }

        public static void AddUnique<T>(this IList<T> _this, T item, Func<T, T, bool> _equalityComparer)
        {
            Func<T, bool> func = x => _equalityComparer(x, item);

            if (_this.Any(func))
                _this.Remove(_this.First(func));
            _this.Add(item);
        }

        public static void InsertUnique<T>(this IList<T> _this, int index, T item)
        {
            if (_this.Contains(item))
                _this.Remove(item);
            _this.Insert(index, item);
        }

        public static void InsertRangeUnique<T>(this IList<T> _this, int index, IEnumerable<T> items)
        {
            foreach (var item in items.Reverse())
                InsertUnique(_this, index, item);
        }

        public static void InsertInOrder<T, U>(this IList<T> _this, T item, Func<T, U> selector, Func<U, U, int> comparer)
        {
            bool added = false;

            for (int i = 0; i < _this.Count; i++)
            {
                if (comparer(selector(_this[i]), selector(item)) >= 0)
                {
                    _this.InsertUnique(i, item);
                    added = true;
                    break;
                }
            }

            // if we haven't added it, add it to the end of the list. 
            if (!added)
                _this.AddUnique(item);
        }

        public static void InsertRangeInOrder<T, U>(this IList<T> _this, IEnumerable<T> others, Func<T, U> selector, Func<U, U, int> comparer)
        {
            foreach (T item in others)
                _this.InsertInOrder(item, selector, comparer);
        }

        public static void Remove<T>(this IList<T> _this, T item, Func<T, T, bool> _equalityComparer)
        {
            Func<T, bool> func = x => _equalityComparer(x, item);

            for (int i = _this.Count - 1; i >= 0; i--)
                if (func(_this[i]))
                    _this.RemoveAt(i);
        }
    }
}
